
class Token(object):
    def __init__(self, kind, text, at=None, **props):
        self.kind = kind
        self.text = text
        self.at = at
        self.__dict__.update(props)
    def __repr__(self):
        return "%r(%r)" % (self.kind, self.text)


class Error(Exception):
    def __init__(self, token, message):
        Exception.__init__(self)
        self.token = token
        self.message = message
    def __str__(self):
        if hasattr(self.token, 'at'):
            return "%r: %s at %r" % (self.token.at, self.message, self.token)
        else:
            return "%s at %r" % (self.message, self.token)


class SyntaxError(Error):
    pass

class SemanticError(Error):
    pass


class ParseError(SyntaxError):
    pass

class TranslateError(SemanticError):
    pass


class MultipleErrors(Exception):
    def __init__(self, errors):
        self.errors = errors
    def __iter__(self):
        return iter(self.errors)
    def __str__(self):
        return "\n * " + "\n * ".join("%s: %s" % (type(x).__name__, x)
                                      for x in self.errors)
